import { Inject, Injectable, Logger } from '@nestjs/common';
import { type Pool } from 'mysql2/promise';
import { CreateUserDto } from './dto/create-user.dto';
import { BusinessException } from '@/common/excepetion';
import * as bcrypt from 'bcryptjs';
import { IdService } from '@/common/snow-flake';
import { SALT_ROUNDS } from '@/common/constant';
import { User } from './entities/user.entity';

@Injectable()
export class UserService {
  private readonly logger = new Logger(UserService.name);

  constructor(
    @Inject('MYSQL_CONNECTION') private readonly db: Pool,
    private readonly idService: IdService,
  ) {}

  /**
   *  根据账号查询用户
   * @param account
   * @returns
   */
  async findByAccount(account: string): Promise<User | undefined> {
    const sql = `select * from sys_user where account = ?`;
    try {
      const [row] = await this.db.query(sql, [account]);
      return row[0] as User;
    } catch (error) {
      throw new BusinessException({ msg: '数据库查询异常' });
    }
  }

  async findAll() {
    // return this.users.map((u) => ({ id: u.id, account: u.account }));
  }

  async create(
    user: CreateUserDto,
    createBy: string,
  ): Promise<Omit<User, 'password'>> {
    let exists: User | undefined;
    try {
      exists = await this.findByAccount(user.account);
    } catch (e) {
      throw new BusinessException({ msg: '账号校验失败' });
    }
    if (exists) {
      throw new BusinessException({ msg: '账号已存在' });
    }

    const connection = await this.db.getConnection();
    try {
      const id = this.idService.generateId();
      const hashed = await bcrypt.hash(user.password, SALT_ROUNDS);
      const now = new Date();

      const sql = `INSERT INTO sys_user (id, name, account, password, create_by, create_time, update_time, del_flag)
                   VALUES (?, ?, ?, ?, ?, ?, ?, ?)`;
      await connection.execute(sql, [
        id,
        user.name,
        user.account,
        hashed,
        createBy,
        now,
        now,
        0,
      ]);
      return {
        id,
        name: user.name,
        account: user.account,
        createBy,
        createTime: now,
        updateTime: now,
      };
    } catch (error) {
      this.logger.error('新增用户失败', error as Error);
      throw new BusinessException({ msg: '新增用户失败' });
    } finally {
      try {
        connection.release();
      } catch {
        //
      }
    }
  }
}
